/*
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

/*
 *
 *
 *
 *
 *
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package java.util.concurrent;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 核心和最大池大小
 * 1、ThreadPoolExecutord自动调整池大小（见getPoolSize()根据corePoolSize（参见设定的界限） getCorePoolSize() ）和maximumPoolSize（参见getMaximumPoolSize() ）
 * 2、当方法execute(Runnable)中提交了新任务，并且运行的corePoolSize线程少于一个，即使其他工作线程处于空闲状态，也会创建一个新的线程来处理该请求。
 * 3、如果超过corePoolSize但小于maximumPoolSize线程运行，则仅当队列已满时才会创建一个新线程。
 * 4、固定大小的线程池: 通过将corePoolSize和maximumPoolSize设置为相同
 * 5、无限并发的线程池: 通过将maximumPoolSize设置为本质上无限制的值（如Integer.MAX_VALUE  最典型的是，核心和最大池大小只能在构建时进行设置，但也可以使用setCorePoolSize(int)和setMaximumPoolSize(int)进行动态 更改 。
 * <p>
 * <p>
 * 按需施工
 * 默认情况下，即使核心线程最初创建并且只有在新任务到达时才启动，但是可以使用方法prestartCoreThread()或prestartAllCoreThreads()动态地覆盖 。
 * 如果您使用非空队列构建池，则可能需要预先提供线程。
 * <p>
 * ThreadFactory创建新线程
 * 如果没有另外指定，则使用Executors.defaultThreadFactory() ，它创建所有线程与所有相同的ThreadGroup并且具有相同的优先级和非守护进程状态NORM_PRIORITY 。
 * 通过提供不同的ThreadFactory，您可以更改线程的名称，线程组，优先级，守护进程状态等。
 * 如果ThreadFactory在从newThread返回null请求时无法创建线程，则执行程序将继续，但可能无法执行任务 线程应该拥有“modifyThread” RuntimePermission 。
 * 如果使用池的工作线程或其他线程不具有此权限，则服务可能会降级：配置更改可能不会及时生效，并且关闭池可能仍处于可能终止但未完成的状态。
 * <p>
 * <p>
 * 活着的时代
 * 1、如果池当前具有多于corePoolSize线程，则如果空闲超过keepAliveTime（见getKeepAliveTime(TimeUnit) ），则多余的线程将被终止。当池未被主动使用时减少资源消耗的方法。
 * 2、如果稍后池变得更加活跃，将构建新的线程。 此参数也可以使用方法setKeepAliveTime(long, TimeUnit)动态更改 。
 * 使用值Long.MAX_VALUE TimeUnit.NANOSECONDS有效地禁用空闲线程在关闭之前终止。 默认情况下，仅当存在多于corePoolSize线程时，保持活动策略才适用。
 * 但是方法allowCoreThreadTimeOut(boolean)也可以用于将这个超时策略应用于核心线程，只要keepAliveTime值不为零。
 * <p>
 * <p>
 * 排队
 * 任何BlockingQueue可用于传送和保留提交的任务。 这个队列的使用与池大小相互作用：
 * 1、如果少于corePoolSize线程正在运行，Executor总是喜欢添加一个新线程，而不是排队。
 * 2、如果corePoolSize或更多的线程正在运行，Executor总是喜欢排队请求而不是添加一个新的线程。
 * 3、如果请求无法排队，则会创建一个新线程，除非这将超出maximumPoolSize，否则任务将被拒绝。
 * <p>
 * <p>
 * 排队有三种一般策略：
 * 1、直接切换 一个工作队列的一个很好的默认选择是一个SynchronousQueue ，将任务交给线程，无需另外控制。
 * 在这里，如果没有线程可以立即运行，那么尝试排队任务会失败，因此将构建一个新的线程。
 * 处理可能具有内部依赖关系的请求集时，此策略可避免锁定。
 * 直接切换通常需要无限制的maximumPoolSizes，以避免拒绝新提交的任务。
 * 这反过来允许无限线程增长的可能性，当命令继续以平均速度比他们可以处理的速度更快地到达时。
 * 2、无界队列 使用无界队列（例如LinkedBlockingQueue没有预定容量）会导致新的任务，在队列中等待，当所有corePoolSize线程都很忙。
 * 因此，不会再创建corePoolSize线程。 （因此，最大值大小的值没有任何影响。）每个任务完全独立于其他任务时，这可能是适当的，因此任务不会影响其他执行;
 * 例如，在网页服务器中。 虽然这种排队风格可以有助于平滑瞬态突发的请求，但是当命令继续达到的平均速度比可以处理的速度更快时，它承认无界工作队列增长的可能性。
 * 3、有边界的队列。 有限队列（例如， ArrayBlockingQueue ）有助于在使用有限maxPoolSizes时防止资源耗尽，但可能更难调整和控制。
 * 队列大小和最大池大小可能彼此交易：使用大队列和小型池可以最大限度地减少CPU使用率，OS资源和上下文切换开销，但可能导致人为的低吞吐量。
 * 如果任务频繁阻塞（例如，如果它们是I / O绑定），则系统可能能够安排比您允许的更多线程的时间。 使用小型队列通常需要较大的池大小，这样可以使CPU繁忙，
 * 但可能会遇到不可接受的调度开销，这也降低了吞吐量。
 * <p>
 * <p>
 * 钩子方法
 * 该类提供了在每个任务执行之前和之后调用的protected覆盖的beforeExecute(Thread, Runnable)和afterExecute(Runnable, Throwable)方法。
 * 这些可以用来操纵执行环境;
 * 例如，重新初始化ThreadLocals，收集统计信息或添加日志条目。
 * 另外，方法terminated()可以被覆盖，以执行执行程序完全终止后需要执行的任何特殊处理。
 * 如果钩子或回调方法抛出异常，内部工作线程可能会失败并突然终止。
 * <p>
 * 队列维护
 * 方法getQueue()允许访问工作队列以进行监视和调试。
 * 强烈不鼓励将此方法用于任何其他目的。
 * 当提供大量排队任务被取消时，两种提供的方法remove(Runnable)和purge()可用于协助进行存储回收。
 * <p>
 * <p>
 * 定稿
 * 即不再在程序中引用， 并没有剩余的线程将成为池shutdown自动。 如果您希望确保未引用的池被回收，即使用户忘记调用shutdown() ，则必须安排未使用的线程最终死机，通过设置适当的保持活动时间，使用零个核心线程的下限和/或设置allowCoreThreadTimeOut(boolean) 。
 */


public class ThreadPoolExecutor extends AbstractExecutorService {


    // ----------------------------------------------------------------------------------------------------------
    // 表示低29位的值，用于表示线程池中工作线程的数量
    private static final int COUNT_BITS = Integer.SIZE - 3;      // 29

    // 线程池的生命周期
    // 运行状态
    // 线程池初始化后，就处于该状态：
    // 此时，线程池可以接受新任务并且处理任务
    private static final int RUNNING = -1 << COUNT_BITS;  // 11100000...   111

    // 关闭状态
    // 调用shutdown()方法时，就处于该状态：
    // 此时，shutdown()方法之后不能再提交新任务，线程池会把shutdown()方法之前提交的任务按照线程池工作原理的步骤都处理完毕
    private static final int SHUTDOWN = 0 << COUNT_BITS;  // 00000000...   000

    // 停止状态
    // 用shutdownNow()方法时，就处于该状态：
    // 此时，shutdownNow()方法之后不能再提交新任务，线程池不处理已经提交到任务队列中的任务，线程池尝试中断正在执行的工作线程
    private static final int STOP = 1 << COUNT_BITS;  // 00100000...   001

    // 整理状态
    // 线程池内部自己使用的状态：当线程池queue任务队列为空，hashset<worker>为空时，就是该状态
    // 该状态是由关闭状态/停止状态转变而来的。当处于整理状态时，线程池会调用terminated()钩子方法
    private static final int TIDYING = 2 << COUNT_BITS;  // 01000000...   010

    // 终结状态
    // 当钩子方法terminated()执行完毕之后，线程池由整理状态转变为终结状态。
    // 钩子方法是线程池自动调用的。
    private static final int TERMINATED = 3 << COUNT_BITS;  // 01100000...   011

// ----------------------------------------------------------------------------------------------------------

    // 存放线程池运行状态 (runState) 和 线程池内有效线程的数量 (workerCount)
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));


    private static int ctlOf(int rs, int wc) {
        return rs | wc;
    }

    /*
     * 用于表示线程池中工作线程的数量的最大值，等于2^29-1
     * workerCount限制为（2^29）-1（约5亿）个线程，而不是（2^31）-1（20亿）个可表示的线程
     * 如果将来出现此问题，可以将变量更改为AtomicLong，并调整下面的移位/掩码常数。但是，在需要之前，使用int可以使这段代码更快、更简单
     */
    private static final int CAPACITY = (1 << COUNT_BITS) - 1; // =000 11111...


    private static int runStateOf(int c) {
        return c & ~CAPACITY;
    }

    private static int workerCountOf(int c) {
        return c & CAPACITY;
    }

// ----------------------------------------------------------------------------------------------------------


    /*
     * runStateLessThan方法用于判断线程池的状态是否小于某个状态
     */
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    /*
     * runStateAtLeast方法用于判断线程池的状态是否大于等于某个状态
     */
    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    /*
     * isRunning方法用于判断线程池的状态是否是RUNNING状态
     */
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    /**
     * 该方法用于增加工作线程的数量，如果增加成功则返回true，否则返回false
     */
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    /**
     * 该方法用于减少工作线程的数量，如果减少成功则返回true，否则返回false
     */
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    /**
     * 该方法用于设置线程池的状态，如果设置成功则返回true，否则返回false
     */
    private void decrementWorkerCount() {
        do {
        } while (!compareAndDecrementWorkerCount(ctl.get()));
    }


// ----------------------------------------------------------------------------------------------------------
    /**
     * 线程池的状态锁，对线程池状态（比如线程池大小、runState等）的改变都要使用这个锁
     */
    private final ReentrantLock mainLock = new ReentrantLock();

    /**
     * 用于保存工作线程的集合
     */
    private final HashSet<Worker> workers = new HashSet<Worker>();

    /**
     * 线程池的条件锁，用mainLock创建的，在线程池的状态发生改变时，会使用这个条件锁来通知所有等待的线程
     */
    private final Condition termination = mainLock.newCondition();

    /**
     * 这是一个动态的变量
     * largestPoolSize表示线程池中曾经出现过的最大线程数，即在线程池的整个生命周期中，曾经有多少个线程同时处于活动状态。
     * 所以说largestPoolSize是小于等于maximumPoolSize的。
     * 它的值可以通过ThreadPoolExecutor的getLargestPoolSize()方法获取。
     */
    private int largestPoolSize;

    /**
     * 表示已经完成的任务数量
     */
    private long completedTaskCount;

// ----------------------------------------------------------------------------------------------------------

    // 线程池核心参数

    /*
     * 核心参数：任务阻塞队列
     */
    private final BlockingQueue<Runnable> workQueue;

    /**
     * 核心参数：线程工厂,所有线程都是使用此工厂创建的（通过方法addWorker）
     */
    private volatile ThreadFactory threadFactory;

    /**
     * 核心参数：拒绝策略
     */
    private volatile RejectedExecutionHandler handler;

    /**
     * 核心参数：等待工作的空闲线程的超时时间
     */
    private volatile long keepAliveTime;

    /**
     * 核心参数：
     * 如果为false，核心线程即使在空闲时也会保持活动状态。
     * 如果为true ，核心线程将使用keepAliveTime超时等待工作。
     */
    private volatile boolean allowCoreThreadTimeOut;

    /**
     * 核心参数：核心池大小是保持活动的最小工作线程数（不允许超时等），
     * 除非设置了allowCoreThreadTimeOut，在这种情况下，最小值为零。
     */
    private volatile int corePoolSize;

    /**
     * 核心参数：最大池大小,这包括核心线程和临时增加的线程
     * 当任务量增加且工作队列已满时，线程池会尝试创建更多的线程，但数量不会超过此上限
     * 取值范围是-2,147,483,648到2,147,483,647,请注意，实际最大值在内部受到容量的限制
     */
    private volatile int maximumPoolSize;

    /**
     * 拒绝策略,默认是被拒绝的任务的处理程序,抛出一个 {@code RejectedExecutionException}
     */
    private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();


    private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread");

    private final AccessControlContext acc;


// ----------------------------------------------------------------------------------------------------------


    // 构造方法

    /**
     * @throws IllegalArgumentException 如果以下某项成立：
     *                                  {@code corePoolSize < 0}     核心线程保持一个及以上
     *                                  {@code keepAliveTime < 0}    最大时间不能为0
     *                                  {@code maximumPoolSize <= 0} 最大线程数不能为负数
     *                                  {@code maximumPoolSize < corePoolSize} 核心线程数一定要大于最大线程数
     * @throws NullPointerException     if {@code workQueue} is null
     */
    public ThreadPoolExecutor(int corePoolSize,     // 核心线程数，空闲时仍保留在池中的线程数
                              int maximumPoolSize,  // 最大线程数
                              long keepAliveTime,   // 线程池中的线程数量大于corePoolSize 的时候，如果这时没有新的任务提交，核心线程外的线程不会立即销毁，而是会等待，直到等待的时间超过了 keepAliveTime才会被回收销毁。
                              TimeUnit unit,        // keepAliveTime时间单位
                              BlockingQueue<Runnable> workQueue) { // 在执行任务之前用于保存任务的队列
        this(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                Executors.defaultThreadFactory(),
                defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                Executors.defaultThreadFactory(),
                handler);
    }


    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0                      // 核心线程保持一个及以上
                || maximumPoolSize <= 0           // 最大线程数不能为负数
                || maximumPoolSize < corePoolSize // 最大线程数一定要大于等于核心线程数
                || keepAliveTime < 0)             // 最大时间不能为0
            throw new IllegalArgumentException();

        if (workQueue == null                     // 任务队列不能为null
                || threadFactory == null          // 线程工厂不能为null
                || handler == null)               // 拒绝策略不能为null
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }


    /**
     * 执行任务.任务可以在新线程或现有的合并的线程中执行
     * 如果任务无法提交执行，由于此执行程序已关闭或已达到其容量，该任务将由当前的RejectedExecutionHandler处理。
     *
     * @param command 要执行的任务
     * @throws RejectedExecutionException 由RejectedExecutionHandler自行 RejectedExecutionHandler ，如果任务不能被接受执行
     * @throws NullPointerException       if {@code command} is null
     */
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         *  线程池任务执行流程
         *  1、工作线程数量小于核心数量，创建核心线程，并将任务交给该核心线程去执行；
         *  2、达到核心线程数量，将任务加入任务队列；
         *  3、任务队列满了，创建非核心线程，并将任务交给该非核心线程去执行；
         *  4、线程数达到最大数量，队列也满了，则执行拒绝策略；
         */

        // 下面会涉及到 3 步 操作
        // 1.首先判断当前线程池中执行的任务数量是否小于 corePoolSize
        // 如果小于的话，通过addWorker(command, true)新建一个线程，并将任务(command)添加到该线程中；然后，启动该线程从而执行任务。
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }

        // 2.如果当前执行的任务数量大于等于 corePoolSize 的时候就会走到这里，表明创建新的线程失败。
        // 通过 isRunning 方法判断线程池状态，线程池处于 RUNNING 状态并且队列可以加入任务，该任务才会被加入进去
        if (isRunning(c) && workQueue.offer(command)) {
            // 再次获取线程池状态
            // 如果线程池状态不是 RUNNING 状态就需要从任务队列中移除任务，并尝试判断线程是否全部执行完毕。同时执行拒绝策略。
            int recheck = ctl.get();
            if (!isRunning(recheck) && remove(command))
                reject(command);
            // 如果线程数是0，就创建非核心线程（任务是null，会从阻塞队列中拉取任务）
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
         //3. 通过addWorker(command, false)新建一个线程，并将任务(command)添加到该线程中；然后，启动该线程从而执行任务。
         // 传入 false 代表增加线程时判断当前线程数是否少于 maxPoolSize
         //如果addWorker(command, false)执行失败，则通过reject()执行相应的拒绝策略的内容。
        } else if (!addWorker(command, false))
            // 如果创建Worker失败说明已经达到最大线程数了，则执行拒绝策略
            reject(command);
    }





    private void advanceRunState(int targetState) {
        for (; ; ) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                    ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }


    final void tryTerminate() {
        for (; ; ) {
            int c = ctl.get();
            if (isRunning(c) ||
                    runStateAtLeast(c, TIDYING) ||
                    (runStateOf(c) == SHUTDOWN && !workQueue.isEmpty()))
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

    private void checkShutdownAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (Worker w : workers)
                    security.checkAccess(w.thread);
            } finally {
                mainLock.unlock();
            }
        }
    }

    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

    private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

    private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }

    private static final boolean ONLY_ONE = true;

    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }

    void onShutdown() {
    }

    final boolean isRunningOrShutdown(boolean shutdownOK) {
        int rs = runStateOf(ctl.get());
        return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
    }

    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        q.drainTo(taskList);
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

    /*
     * Methods for creating, running and cleaning up after workers
     */

    /**
     * 检查是否可以根据当前池状态和给定的绑定（核心或最大值）添加新的worker。
     * 如果是这样，则相应地调整worker计数
     * 如果可能，则创建并启动一个新worker，将firstTask作为其第一个任务运行。
     * 如果池已停止或符合关闭条件，
     * 则此方法返回false。如果线程工厂在被询问时未能创建线程，它也会返回false。如果线程创建失败，无论是由于线程工厂返回null，
     * 还是由于异常（通常是thread.start（）中的OutOfMemoryError），我们都会彻底回滚。
     *
     * @param firstTask firstTask新线程应首先运行的任务（如果没有，则为null）。
     *                  当线程数少于corePoolSize时（在这种情况下，我们总是启动一个线程），或者当队列已满时（在那种情况下我们必须绕过队列），
     *                  使用初始的第一个任务（在方法execute（）中）创建Workers来绕过队列。
     *                  最初，空闲线程通常是通过预启动CoreThread创建的，或者用来替换其他垂死的worker。
     * @param core      如果为true，则使用corePoolSize作为绑定值，否则使用maximumPoolSize。（这里使用布尔指示符而不是值，以确保在检查其他池状态后读取新值）。
     * @return true if successful
     */
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (; ; ) {
            // 再次获取线程池 runState状态值
            int c = ctl.get();
            int rs = runStateOf(c);

            // 检查是否允许提交任务
            // 1、如果非运行状态  RUNNING
            // 2、不是【线程池是停止状态并且传入的任务是null并且workQueue不等于空】这种情况
            // 同时满足以下两个条件,return false
            if (rs >= SHUTDOWN &&
                    !(rs == SHUTDOWN &&
                            firstTask == null &&
                            !workQueue.isEmpty()))
                return false;

            // 使用死循环保证添加线程成功
            for (; ; ) {
                int wc = workerCountOf(c);
                // 校验线程数是否超过容量限制
                // 1、线程数饱和容量了(大概5亿线程)
                // 2、线程数已经达到最大线程数则不能再新建线程
                // 只要满足以下一个条件, return false
                if (wc >= CAPACITY ||
                        wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;

                // 使用CAS修改线程数,保证线程安全
                // 走到这里说明线程池可以创建新线程
                // 则将线程数量 加1,因为后面要创建线程了,并跳出总循环
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();
                // 如果当前的运行状态已经和最开始获取的状态不一样了
                // 如果线程池状态改变了,则从头再来
                // 回到retry:但是因为这里用的是continue，所以程序往后执行还是会再次进入到该循环继续执行上面的判断
                if (runStateOf(c) != rs)
                    continue retry;
            }
        }

        // 如果上面的条件满足，则会把工作线程数量加1，然后执行下面创建线程的动作

        boolean workerStarted = false;  // 标记是否启动了工作线程
        boolean workerAdded = false;    // 标记是否成功添加了工作线程
        Worker w = null;                // 要创建的Worker对象
        try {
            // 把任务和新线程包装成一个 Worker
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;   // 获取线程池的锁
                mainLock.lock(); // 在读取线程池状态的时候就应该上锁，防止有并发操作破坏程序的一致性，上下不一致
                try {
                    // 再次校验线程池状态是否异常
                    int rs = runStateOf(ctl.get());
                    if (rs < SHUTDOWN ||
                            (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive())  // 预先检查t是否可启动
                            throw new IllegalThreadStateException();
                        // 添加到工作线程队列。 workers是线程池中存放工作线程的集合
                        // 增加work每一个线程池都持有一个workers集合，里面存储着线程池的所有worker，也就是所有线程
                        workers.add(w);
                        int s = workers.size();
                        // 记录线程数历史峰值
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    // 启动线程
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (!workerStarted)
                // 通过源码,可以总结出创建Worker失败的原因:
                // 1、在添加时线程池被停止了
                // 2、添加核心线程池时，超过核心线程池数量
                // 3、添加非核心线程池时，超过最大线程池数量
                // 4、Worker 对象初始化未完成时就被使用，即 thread 对象还未完全创建
                // 5、当前线程正在被运行（防止出现重复运行，抛出异常）
                // 6、线程创建过多，导致 OOM
                addWorkerFailed(w);
        }
        return workerStarted;
    }

    /**
     * 通过源码,可以总结出创建Worker失败的原因:
     * 1、在添加时线程池被停止了
     * 2、添加核心线程池时，超过核心线程池数量
     * 3、添加非核心线程池时，超过最大线程池数量
     * 4、Worker 对象初始化未完成时就被使用，即 thread 对象还未完全创建
     * 5、当前线程正在被运行（防止出现重复运行，抛出异常）
     * 6、线程创建过多，导致 OOM
     */
    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 移除添加失败的worke
            if (w != null)
                workers.remove(w);
            // 减少worker数量
            decrementWorkerCount();
            // 尝试终止线程池
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }


    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && !workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }


    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (; ; ) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                    && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                        workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }


    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                                runStateAtLeast(ctl.get(), STOP))) &&
                        !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x;
                        throw x;
                    } catch (Error x) {
                        thrown = x;
                        throw x;
                    } catch (Throwable x) {
                        thrown = x;
                        throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }



    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }


    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

    public boolean isShutdown() {
        return !isRunning(ctl.get());
    }


    public boolean isTerminating() {
        int c = ctl.get();
        return !isRunning(c) && runStateLessThan(c, TERMINATED);
    }

    public boolean isTerminated() {
        return runStateAtLeast(ctl.get(), TERMINATED);
    }

    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (; ; ) {
                if (runStateAtLeast(ctl.get(), TERMINATED))
                    return true;
                if (nanos <= 0)
                    return false;
                nanos = termination.awaitNanos(nanos);
            }
        } finally {
            mainLock.unlock();
        }
    }


    protected void finalize() {
        SecurityManager sm = System.getSecurityManager();
        if (sm == null || acc == null) {
            shutdown();
        } else {
            PrivilegedAction<Void> pa = () -> {
                shutdown();
                return null;
            };
            AccessController.doPrivileged(pa, acc);
        }
    }











    public void setThreadFactory(ThreadFactory threadFactory) {
        if (threadFactory == null)
            throw new NullPointerException();
        this.threadFactory = threadFactory;
    }

    public ThreadFactory getThreadFactory() {
        return threadFactory;
    }


    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
        if (handler == null)
            throw new NullPointerException();
        this.handler = handler;
    }

    public RejectedExecutionHandler getRejectedExecutionHandler() {
        return handler;
    }


    public void setCorePoolSize(int corePoolSize) {
        if (corePoolSize < 0)
            throw new IllegalArgumentException();
        int delta = corePoolSize - this.corePoolSize;
        this.corePoolSize = corePoolSize;
        if (workerCountOf(ctl.get()) > corePoolSize)
            interruptIdleWorkers();
        else if (delta > 0) {
            // We don't really know how many new threads are "needed".
            // As a heuristic, prestart enough new workers (up to new
            // core size) to handle the current number of tasks in
            // queue, but stop if queue becomes empty while doing so.
            int k = Math.min(delta, workQueue.size());
            while (k-- > 0 && addWorker(null, true)) {
                if (workQueue.isEmpty())
                    break;
            }
        }
    }


    public int getCorePoolSize() {
        return corePoolSize;
    }


    public boolean prestartCoreThread() {
        return workerCountOf(ctl.get()) < corePoolSize &&
                addWorker(null, true);
    }


    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

    public int prestartAllCoreThreads() {
        int n = 0;
        while (addWorker(null, true))
            ++n;
        return n;
    }


    public boolean allowsCoreThreadTimeOut() {
        return allowCoreThreadTimeOut;
    }


    public void allowCoreThreadTimeOut(boolean value) {
        if (value && keepAliveTime <= 0)
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        if (value != allowCoreThreadTimeOut) {
            allowCoreThreadTimeOut = value;
            if (value)
                interruptIdleWorkers();
        }
    }


    public void setMaximumPoolSize(int maximumPoolSize) {
        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
            throw new IllegalArgumentException();
        this.maximumPoolSize = maximumPoolSize;
        if (workerCountOf(ctl.get()) > maximumPoolSize)
            interruptIdleWorkers();
    }


    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }


    public void setKeepAliveTime(long time, TimeUnit unit) {
        if (time < 0)
            throw new IllegalArgumentException();
        if (time == 0 && allowsCoreThreadTimeOut())
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        long keepAliveTime = unit.toNanos(time);
        long delta = keepAliveTime - this.keepAliveTime;
        this.keepAliveTime = keepAliveTime;
        if (delta < 0)
            interruptIdleWorkers();
    }


    public long getKeepAliveTime(TimeUnit unit) {
        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
    }


    public BlockingQueue<Runnable> getQueue() {
        return workQueue;
    }


    public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);
        tryTerminate(); // In case SHUTDOWN and now empty
        return removed;
    }

    public void purge() {
        final BlockingQueue<Runnable> q = workQueue;
        try {
            Iterator<Runnable> it = q.iterator();
            while (it.hasNext()) {
                Runnable r = it.next();
                if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
                    it.remove();
            }
        } catch (ConcurrentModificationException fallThrough) {
            // Take slow path if we encounter interference during traversal.
            // Make copy for traversal and call remove for cancelled entries.
            // The slow path is more likely to be O(N*N).
            for (Object r : q.toArray())
                if (r instanceof Future<?> && ((Future<?>) r).isCancelled())
                    q.remove(r);
        }

        tryTerminate(); // In case SHUTDOWN and now empty
    }


    public int getPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // Remove rare and surprising possibility of
            // isTerminated() && getPoolSize() > 0
            return runStateAtLeast(ctl.get(), TIDYING) ? 0
                    : workers.size();
        } finally {
            mainLock.unlock();
        }
    }


    public int getActiveCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            int n = 0;
            for (Worker w : workers)
                if (w.isLocked())
                    ++n;
            return n;
        } finally {
            mainLock.unlock();
        }
    }


    public int getLargestPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            return largestPoolSize;
        } finally {
            mainLock.unlock();
        }
    }


    public long getTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers) {
                n += w.completedTasks;
                if (w.isLocked())
                    ++n;
            }
            return n + workQueue.size();
        } finally {
            mainLock.unlock();
        }
    }


    public long getCompletedTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers)
                n += w.completedTasks;
            return n;
        } finally {
            mainLock.unlock();
        }
    }


    public String toString() {
        long ncompleted;
        int nworkers, nactive;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            ncompleted = completedTaskCount;
            nactive = 0;
            nworkers = workers.size();
            for (Worker w : workers) {
                ncompleted += w.completedTasks;
                if (w.isLocked())
                    ++nactive;
            }
        } finally {
            mainLock.unlock();
        }
        int c = ctl.get();
        String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
                (runStateAtLeast(c, TERMINATED) ? "Terminated" :
                        "Shutting down"));
        return super.toString() +
                "[" + rs +
                ", pool size = " + nworkers +
                ", active threads = " + nactive +
                ", queued tasks = " + workQueue.size() +
                ", completed tasks = " + ncompleted +
                "]";
    }

    protected void beforeExecute(Thread t, Runnable r) {
    }


    protected void afterExecute(Runnable r, Throwable t) {
    }


    protected void terminated() {
    }


    // 工作线程内部类（Worker）

    /**
     * 每一个Worker类就会绑定一个线程（Worker类有一个成员属性持有一个线程对象）
     * 可以将Worker理解为线程池中执行任务的线程。
     * 但是实际上它并不仅仅是一个线程，Worker里面还会有一些统计信息，存储一些相关的数据。
     */
    private final class Worker extends AbstractQueuedSynchronizer implements Runnable {

        private static final long serialVersionUID = 6138294804551838833L;
        // 工作线程
        final Thread thread;
        // 任务
        Runnable firstTask;
        volatile long completedTasks;

        /**
         * 创建worker,并创建一个新线程(用来执行任务)
         */
        Worker(Runnable firstTask) {
            setState(-1); // 禁止中断，直到runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /**
         * 线程执行入口
         */
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.

        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        public void lock() {
            acquire(1);
        }

        public boolean tryLock() {
            return tryAcquire(1);
        }

        public void unlock() {
            release(1);
        }

        public boolean isLocked() {
            return isHeldExclusively();
        }

        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }


    //  拒绝策略内部类（Policy）

    /**
     * 一个被拒绝的任务的处理程序，直接在 execute方法的调用线程中运行被拒绝的任务，除非执行程序已被关闭，否则这个任务被丢弃
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        public CallerRunsPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

    /**
     * 被拒绝的任务的处理程序，抛出一个 {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                    " rejected from " +
                    e.toString());
        }
    }

    /**
     * 被拒绝的任务的处理程序静默地丢弃被拒绝的任务。
     */
    public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

    /**
     * 被拒绝的任务的处理程序，丢弃最旧的未处理请求，然后重试 execute ，除非执行程序被关闭，在这种情况下，任务被丢弃。
     */
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        public DiscardOldestPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
}
